package val.to.UI;

import java.util.ArrayList;

import val.to.BitmapUtil;
import val.to.Globals;
import val.to.ImageCache;
import val.to.R;
import val.to.Utility;
import val.to.ValtoActivity;
import val.to.common.ITaskCanceler;
import val.to.common.ImageFetcher;
import val.to.common.ImageFetcher.ImageFetcherListener;
import val.to.common.SimpleTaskCanceler;
import val.to.config.Constants;
import val.to.entities.FeedItem;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Parcelable;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageButton;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.ViewSwitcher.ViewFactory;

public class ItemFullScreenActivity extends ValtoActivity implements ViewFactory {
		
	private ArrayList<FeedItem> mItems;
	private int mCurrentItem;

	private TextView mTimeAgo;
	private TextView mUsername;
	private TextView mComment;
	private ImageButton mLeft;
	private ImageButton mRight;
	
	private View mHeaderView;
	private View mFooterView;
	private ProgressBar mProgress;
	private ImageSwitcher mImageSwitcher;
	private ImageView mUserPicture;
	
	private ImageLoadTask mCurrentTask;
	
	private boolean mLoadingDone = true;
	private Animation mFadeInAnim;
	private Animation mFadeOutAnim;
	private boolean mControlsVisible = true;
	
	private MenuButton mMenuButton;
	private boolean mShowComment;
	
	private Handler mHandler;
	private ITaskCanceler mCanceler = new SimpleTaskCanceler(); 

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		//Override the default behavior of reconstructing the activity
		super.onConfigurationChanged(newConfig);
	}
	
	@Override
	protected void onPause() {
		mCanceler.cancel();
		super.onPause();
	}
	
	@Override
    public void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
        setContentView(R.layout.item_full_size);
        
        mFadeInAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
        mFadeOutAnim = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
    
        mHandler = new Handler();
        
        Bundle bundle = getIntent().getExtras();
        mCurrentItem = bundle.getInt("CurrentItem", 0);
        ArrayList<Parcelable> parcelables = bundle.getParcelableArrayList("FeedItems");
        if (parcelables == null){
        	//TODO
        }
        mItems = new ArrayList<FeedItem>(parcelables.size());
        for(Parcelable p : parcelables){
        	mItems.add((FeedItem)p);
        }
        
        mUsername = (TextView)findViewById(R.id.username);
        mComment = (TextView)findViewById(R.id.comment);
        mTimeAgo = (TextView)findViewById(R.id.timeAgo);
        mLeft = (ImageButton)findViewById(R.id.left);
        mRight = (ImageButton)findViewById(R.id.right);
        mFooterView = (View) findViewById(R.id.footer);
        mHeaderView = (View) findViewById(R.id.header);
        mProgress = (ProgressBar) findViewById(R.id.progress);
        mImageSwitcher = (ImageSwitcher) findViewById(R.id.bg);
        mUserPicture = (ImageView) findViewById(R.id.userImage);
        
		mMenuButton = (MenuButton) findViewById(R.id.menuButton);
		mMenuButton.init(this);
        
        mImageSwitcher.setFactory(this);

        mLeft.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mCurrentItem > 0){
			        mImageSwitcher.setInAnimation(AnimationUtils.loadAnimation(ItemFullScreenActivity.this,
			                android.R.anim.slide_in_left));
			        mImageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(ItemFullScreenActivity.this,
			                android.R.anim.slide_out_right));

					mCurrentItem--;
					showCurrentItem();
				}
			}
		});
        
        mRight.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (mCurrentItem < mItems.size() - 1){
			        mImageSwitcher.setInAnimation(AnimationUtils.loadAnimation(ItemFullScreenActivity.this,
			                R.anim.slide_in_right));
			        mImageSwitcher.setOutAnimation(AnimationUtils.loadAnimation(ItemFullScreenActivity.this,
			                R.anim.slide_out_left));

			        
					mCurrentItem++;
					showCurrentItem();
				}
			}
		});
   
        mImageSwitcher.setOnTouchListener(new OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (mLoadingDone && event.getAction() == MotionEvent.ACTION_DOWN ){
					if (mControlsVisible){
						hideControls();
					}
					else{
						showControls();
					}
					return true;
				}
				
				return false;
			}
        });
        
        showCurrentItem();
    }
	
	private void showCurrentItem(){
		
		if (mCurrentTask != null){
			mCurrentTask.cancel(true);
		}
		
		showControls();
		final FeedItem item = mItems.get(mCurrentItem);
				
		long timeDiff = System.currentTimeMillis() - item.getTimestamp().getTime();
		String strTime = Utility.getRoughStringForTimeDiff(timeDiff);
		mTimeAgo.setText(strTime);
		
		mUsername.setText(item.getUsername());
		mComment.setText(item.getComment());
		
		mRight.clearAnimation();
		mLeft.clearAnimation();
		mRight.setVisibility(mCurrentItem == mItems.size() - 1 ? View.INVISIBLE : View.VISIBLE);
		mLeft.setVisibility(mCurrentItem == 0 ? View.INVISIBLE : View.VISIBLE);
		
		Bitmap bmp = ImageCache.getInstanceLarge().tryGetBitmap(item.getImageUri());
		if (bmp != null){
			showBitmap(bmp);
		}
		else{
			mCurrentTask = new ImageLoadTask(item.getImageUri());
			mCurrentTask.execute();		
		}
		
		
		mShowComment = item.getComment() != null && item.getComment().length() > 0;
		mFooterView.setVisibility(mShowComment ? View.VISIBLE : View.INVISIBLE);
		
		final String userGraphPath = String.format(Constants.FB_User_Image_Template, item.getUserId());
		bmp = ImageCache.getInstanceUserPictures().tryGetBitmap(userGraphPath);
		if (bmp != null){
			mUserPicture.setImageBitmap(bmp);
		}
		else{
			mUserPicture.setTag(userGraphPath);
			ImageFetcher fetcher = new ImageFetcher(userGraphPath, new ImageFetcherListener() {
				@Override
				public void onImageFetchCompleted(final Bitmap bmp) {
					ImageCache.getInstanceUserPictures().encache(userGraphPath, bmp);
					mHandler.post(new Runnable() {	
						@Override
						public void run() {
							if (!mUserPicture.getTag().toString().equals(userGraphPath)){    
					             return;
							}
							 
							mUserPicture.setImageBitmap(bmp);						}
					});
				}
			}, mCanceler);
			
			Globals.AsyncTasksQueue.AddTask(fetcher);
		}
	}
	
	private class ImageLoadTask extends AsyncTask<Void, Void, Void>
	{    	
		private String mImageUri;
		private Bitmap mBitmap;
	
		public ImageLoadTask(String imageUri){
			mImageUri = imageUri;
		}
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mImageSwitcher.setImageDrawable(null);
			mProgress.setVisibility(View.VISIBLE);
			mLoadingDone = false;
	 	}
		
		@Override
		protected Void doInBackground(Void... params) {	
			mBitmap =  BitmapUtil.getBitmap(mImageUri);
			return null;
		}
		
		@Override
		protected void onPostExecute(Void v) {
			//Invoked on the UI thread
			if (mBitmap != null){
				if (!isCancelled()){
					showBitmap(mBitmap);
				}
				
				//Encache even if canceled, good change the user will return to it.
				ImageCache.getInstanceLarge().encache(mImageUri, mBitmap);
			}
			else{
				Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.error_image_bw);
				showBitmap(bmp);
			}
		}
	}
	
	private void showBitmap(Bitmap bmp){
		BitmapDrawable bd = new BitmapDrawable(bmp);
		mImageSwitcher.setImageDrawable(bd);
		mProgress.setVisibility(View.INVISIBLE);
		mLoadingDone = true;
	}
	
	private void showControls(){
		if (mControlsVisible){
			return;
		}
		
		if (mShowComment){
			mFooterView.setVisibility(View.VISIBLE);
			mFooterView.startAnimation(mFadeInAnim);
		}
		
		mHeaderView.startAnimation(mFadeInAnim);
		mHeaderView.setVisibility(View.VISIBLE);
		
		if (mCurrentItem > 0){
			mLeft.startAnimation(mFadeInAnim);
			mLeft.setVisibility(View.VISIBLE);
		}		
		if (mCurrentItem < mItems.size() - 1){
			mRight.startAnimation(mFadeInAnim);
			mRight.setVisibility(View.VISIBLE);			
		}
		
		
		mControlsVisible = true;
	}
	
	private void hideControls(){
		if (!mControlsVisible){
			return;
		}
		
		mHeaderView.startAnimation(mFadeOutAnim);
		mHeaderView.setVisibility(View.INVISIBLE);
		
		if (mShowComment){
			mFooterView.startAnimation(mFadeOutAnim);
			mFooterView.setVisibility(View.INVISIBLE);
		}
		
		if (mCurrentItem > 0){
			mLeft.startAnimation(mFadeOutAnim);
			mLeft.setVisibility(View.INVISIBLE);
		}		
		if (mCurrentItem < mItems.size() - 1){
			mRight.startAnimation(mFadeOutAnim);
			mRight.setVisibility(View.INVISIBLE);			
		}
	
		mControlsVisible = false;
	}

	@Override
	public View makeView() {
		ImageView imageView = new ImageView(this);
		imageView.setBackgroundColor(0xFF000000);
		imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
		imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
		return imageView;
	}

	//TODO: not used yet
	private class SwipeDetector extends SimpleOnGestureListener{
        
		// for touch left or touch right events
        private static final int SWIPE_MIN_DISTANCE = 60;   //default is 120
        private static final int SWIPE_MAX_OFF_PATH = 250;
        private static final int SWIPE_THRESHOLD_VELOCITY = 200;

        @Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH){
                    return false;
                }
                
                // right to left swipe
                if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                        onHorizonTouch(true);  // left

                }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                        onHorizonTouch(false); // right   

                }
            } 
            catch (Exception e) {
                // nothing
            }
            return false;
        }
		

        void onHorizonTouch(Boolean toLeft){
            if(toLeft)
            {
            }
            else
            {
            }
        };
	}
}
